package timer2;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;

class Mytask implements Comparable<Mytask>{
    private Runnable task;//当前任务
    private long lastTime;//多长时间后进行这个任务
    public Mytask(Runnable task, long lastTime) {
        this.task = task;
        this.lastTime = System.currentTimeMillis() + lastTime;
    }
    //获取任务
    public Runnable getTask() {
        return this.task;
    }
    //获取多久后进行任务的时间
    public long getLastTime() {
        return this.lastTime;
    }
    public int compareTo(Mytask mytask){
        return (int)(this.lastTime - mytask.getLastTime());
    }
}
//时钟
class MyTimer {
    //该定时器的锁
    private Object locker = new Object();
    //用阻塞队列来存放任务,并且排序，让时间安排早的任务放在前面
    private BlockingQueue<Mytask> queue = new PriorityBlockingQueue<>();
    //创建一个线程，使其在规定时间内，完成安排的任务
    public MyTimer(){
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while(true) {
                    synchronized (locker) {
                        try {
                            //获取该任务什么时候执行的时间
                            Mytask mytask = queue.take();
                            long taskTime = mytask.getLastTime();
                            //获取当前时间
                            long nowTime = System.currentTimeMillis();
                            //检测是否到点
                            if (taskTime <= nowTime) {
                                //到点了就执行
                                mytask.getTask().run();
                            } else {
                                //没到点，就放回去,并阻塞等待这么长的时间
                                queue.put(mytask);
                                locker.wait(taskTime - nowTime);
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
        t.start();
    }
    //安排任务
    public void schedule(Runnable task, long waitTime) throws InterruptedException {
        queue.put(new Mytask(task, waitTime));
        //这里的synchronized是因为:
        //避免空打一炮的情况，这样若一个新的更早的任务来了，就执行不上了
        synchronized(locker){
            locker.notify();
        }
    }

}

public class Test2 {
    public static void main(String[] args) throws InterruptedException {
        MyTimer myTimer = new MyTimer();
        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("这是一个第2s执行的任务");
            }
        }, 2000);
        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("这是一个5s后执行的任务");
            }
        }, 5000);
        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("这是一个6s后执行的任务");
            }
        }, 6000);
    }
}
